package com.qpx.jxcmessage.confirm;


import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;


@Slf4j
@Component(value = "consumer-message")
@RabbitListener(queues = "queue-confirm-test")
public class Consumer {


    @RabbitHandler
    public void getMessage(String msg, Channel channel, Message message) throws IOException {
        try {
            log.info("queue-confirm-test:收到消息：{}",msg);
            String a = null;
            a.toString();
            //处理业务逻辑 1000行代码
            //basicAck：表示成功确认，使用此回执方法后，消息会被 rabbitmq broker 删除。
            //deliveryTag：表示消息投递序号，每次消费消息或者消息重新投递后， deliveryTag都会增加。手动消息确认模式下，我们可以对指定 deliveryTag的消息进行 ack、 nack、 reject等操作。
            //multiple：是否批量确认，值为 true 则会一次性 ack所有小于当前消息 deliveryTag 的消息。
            //举个栗子： 假设我先发送三条消息 deliveryTag分别是5、6、7，可它们都没有被确认，当我发第四条消息此时 deliveryTag为8， multiple设置为 true，会将5、6、7、8的消息全部进行确认。
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

        } catch (Exception e) {
            e.printStackTrace();
            if (message.getMessageProperties().getRedelivered()){
                log.info("拒绝处理消息。。。。。");
                //basicReject：拒绝消息，与 basicNack区别在于不能进行批量操作，其他用法很相似。
                //requeue：值为 true 消息将重新入队列。
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else {
                log.info("消息出现异常。。。。进入队列重新发送.。。。。。。");
                //basicNack ：表示失败确认，一般在消费消息业务异常时用到此方法，可以将消息重新投递入队列。
                //deliveryTag：表示消息投递序号。
                //multiple：是否批量确认。
                //requeue：值为 true 消息将重新入队列。
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }
    }

}
